package cn.xyt.util;

import java.net.InetSocketAddress;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import io.netty.channel.Channel;

@Service
public class DeviceCache {
	private static final Logger LOG = LoggerFactory.getLogger(DeviceCache.class);
	private static Cache<String, Object> cache = null;

	public static InetChannel get(String key) {
		InetChannel channel = null;
		try {
			channel = (InetChannel) cache.getIfPresent(key);
		} catch (Exception e) {
			LOG.debug("get device socket[sn={}] from cache faild, error={}", key, e.getMessage());
		}
		return channel;
	}

	public static void set(String key, InetChannel channel) {
		cache.put(key, channel);
	}

	public static Map<String, Object> asMap(){
		return cache.asMap();
	}
	
	public static Cache<String, Object> cache(){
		return cache;
	}
	
	public static void remove(String key) {
		try {
			cache.invalidate(key);
		} catch (Exception e) {
			LOG.debug("remove device[sn={}] from cache faild, error={}", key, e.getMessage());
		}
	}
	
	public static boolean containsValue(Object value){
		return cache.asMap().containsValue(value);
	}

	@PostConstruct
	public void init() {
		if (cache == null) {
			cache = CacheBuilder.newBuilder().build();
		}
	}

	@PreDestroy
	public void destroy() {
		try {
			cache.invalidateAll();
		} catch (Exception e) {
			LOG.debug("remove all from cache faild, error={}", e.getMessage());
		}
	}
	
	
	public static class InetChannel{
		public InetSocketAddress address;
		public Channel channel;
		public InetChannel(InetSocketAddress address, Channel channel) {
			this.address = address;
			this.channel = channel;
		}
		
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((address == null) ? 0 : address.hashCode());
			result = prime * result + ((channel == null) ? 0 : channel.hashCode());
			return result;
		}
		
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			InetChannel other = (InetChannel) obj;
			if (address == null) {
				if (other.address != null)
					return false;
			} else if (!address.equals(other.address))
				return false;
			if (channel == null) {
				if (other.channel != null)
					return false;
			} else if (!channel.equals(other.channel))
				return false;
			return true;
		}
		
		
		
		
	}
}
